<?php


namespace App\Services;


class IdCardService
{

    public static $connectTimeout = 30;//30 second
    public static $readTimeout = 80;//80 second
    const IDURL='/v2/identity/auth/api/ocr/idcard';
    const FACEURL='/v2/identity/auth/api/individual/face';
    const FACECheck='/v2/identity/auth/api/individual/{flowId}/face/check';
    const HOST='https://openapi.esign.cn';
    private $emblemImg;

    public static function build($post=[])
    {
        $paramStr=json_encode($post,JSON_UNESCAPED_SLASHES);
        if($paramStr=="[]"){
            $paramStr='{}';
        }
        return self::doCommHttp( 'POST', self::IDURL,$paramStr);
    }

    //人脸识别
    public static function indivAuthUrl($post=[])
    {
        $paramStr=json_encode($post,JSON_UNESCAPED_SLASHES);
        if($paramStr=="[]"){
            $paramStr='{}';
        }
        return self::doCommHttp( 'POST', self::FACEURL,$paramStr);
    }

    //人脸验证
    public static function faceCheck($flowId)
    {
        $faceAuth = str_replace('{flowId}',$flowId,self::FACECheck);

        $paramStr='{}';
        return self::doCommHttp( 'GET', $faceAuth,$paramStr);
    }
    /**
     * 获取人脸识别url
     * @param $post
     * @return void
     */
    public static function getFaceUrl($post=[])
    {
        $paramStr=json_encode($post,JSON_UNESCAPED_SLASHES);
        if($paramStr=="[]"){
            $paramStr='{}';
        }
        return self::doCommHttp( 'POST', self::FACEURL,$paramStr);

    }

    /**
     * 常规请求
     * @param $reqType
     * @param $url
     * @param $paramStr
     * @return EsignResponse
     */
    public  static function doCommHttp($reqType, $url, $paramStr){
//		get和delete方式请求不能携带body体
        if(strtoupper($reqType)=="GET"||strtoupper($reqType)=="DELETE"){
            $paramStr=null;
        }
        //对body体做md5摘要
        $contentMd5=self::getContentMd5($paramStr);

        //传入生成的bodyMd5,加上其他请求头部信息拼接成字符串,整体做sha256签名
        $reqSignature = self::getSignature($reqType,"*/*","application/json; charset=UTF-8",$contentMd5,"","",$url);
        $url=self::HOST.$url;
        return self::sendHttp($reqType, $url, self::buildCommHeader($contentMd5,$reqSignature),$paramStr);
    }

    /**
     * 构造头部信息
     * @param $contentMD5
     * @param $reqSignature
     * @return array
     */
    public static function buildCommHeader($contentMD5,$reqSignature){
        $headers = array(
            'X-Tsign-Open-App-Id:'.config('esign.APPID'),
            'X-Tsign-Open-Ca-Timestamp:'.self::getMillisecond(),
            'Accept:*/*',
            'X-Tsign-Open-Ca-Signature:'.$reqSignature,
            'Content-MD5:'.$contentMD5,
            'Content-Type:application/json; charset=UTF-8',
            'X-Tsign-Open-Auth-Mode:Signature'
        );
        return $headers;
    }
    /**
     * 生成13位时间戳
     * @return float
     */
    public static function getMillisecond()
    {
        list($t1, $t2) = explode(' ', microtime());
        return (float)sprintf('%.0f', (floatval($t1) + floatval($t2)) * 1000);
    }


    /**
     * 获取MD5
     * @param $bodyData
     * @return string
     */
    public static function getContentMd5($bodyData)
    {
        return base64_encode(md5($bodyData, true));
    }

    /**
     * 生成签名
     * @param $httpMethod
     * @param $accept
     * @param $contentType
     * @param $contentMd5
     * @param $date
     * @param $headers
     * @param $url
     * @return string
     */
    public static function getSignature($httpMethod, $accept, $contentType, $contentMd5, $date, $headers, $url)
    {

        $stringToSign = $httpMethod . "\n" . $accept . "\n" . $contentMd5 . "\n" . $contentType . "\n" . $date . "\n" . $headers;
        if ($headers != '') {
            $stringToSign .= "\n" . $url;
        } else {
            $stringToSign .= $url;
        }
        $signature = hash_hmac("sha256", utf8_encode($stringToSign), utf8_encode(config('esign.SECRET')), true);
        $signature = base64_encode($signature);
        return $signature;
    }



    //常规请求类
    public static function sendHttp($reqType='GET', $url, $headers=array(), $param=null)
    {
        $logData = [
            'url' => $url,
            'httpMethod' => $reqType,
            'data' => $param,
            'header' => $headers
        ];
//        var_dump($logData);
//        $flag=Factory::getDebug();
//        if($flag) {
//            self::writeLog('curl data:');
//            self::writeLog($logData);
//            var_dump("请求url" . $url);
//            var_dump("请求参数" . $param);
//            var_dump("请求方法" . $reqType);
//        }
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $reqType);
//        if (Factory::getENABLEHTTPPROXY()) {
//            curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
//            curl_setopt($ch, CURLOPT_PROXY, Factory::getHTTPPROXYIP());
//            curl_setopt($ch, CURLOPT_PROXYPORT, Factory::getHTTPPROXYPORT());
//            curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
//        }
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_FAILONERROR, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $postData = is_array($param) ? json_encode($param, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) : $param;
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
        if (self::$readTimeout) {
            curl_setopt($ch, CURLOPT_TIMEOUT, self::$readTimeout);
        }
        if (self::$connectTimeout) {
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, self::$connectTimeout);
        }
        //https request
        if (strlen($url) > 5 && strtolower(substr($url, 0, 5)) == "https") {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        }
        if (is_array($headers) && 0 < count($headers)) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        }
        $curlRes = curl_exec($ch);
//        if($flag){
//            self::writeLog('curl response:');
//            self::writeLog($curlRes);
//            var_dump("响应" . $curlRes);
//        }


        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $curlRes=json_decode($curlRes,true);
//        var_dump($curlRes);
        curl_close($ch);
        return compact('curlRes','httpCode');
    }

    /**
     * 上传文件
     * @param $uploadUrls
     * @param $contentMd5
     * @param $fileContent
     * @param $ContenType
     * @return EsignResponse
     */
    public static function upLoadFileHttp($uploadUrls, $contentMd5, $fileContent,$ContenType){
        $header = array(
            'Content-Type:'.$ContenType,
            'Content-Md5:' . $contentMd5
        );


        $curl_handle = curl_init();
        curl_setopt($curl_handle, CURLOPT_URL, $uploadUrls);
        curl_setopt($curl_handle, CURLOPT_FILETIME, true);
        curl_setopt($curl_handle, CURLOPT_FRESH_CONNECT, false);
//            curl_setopt($curl_handle, CURLOPT_HEADER, true); // 输出HTTP头 true
        curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl_handle, CURLOPT_TIMEOUT, 5184000);
        curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 120);
        curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl_handle, CURLOPT_SSL_VERIFYHOST, false);

        curl_setopt($curl_handle, CURLOPT_HTTPHEADER, $header);
        curl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, 'PUT');

        curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $fileContent);
        if (is_array($header) && 0 < count($header)) {
            curl_setopt($curl_handle, CURLOPT_HTTPHEADER, $header);
        }
        $curlRes = curl_exec($curl_handle);
        $httpCode = curl_getinfo($curl_handle, CURLINFO_HTTP_CODE);
        self::writeLog($curlRes);
        curl_close($curl_handle);
        return new EsignResponse($httpCode,$curlRes);
    }



    static function writeLog($text) {
        if(is_array($text) || is_object($text)){
            $text = json_encode($text);
        }
        file_put_contents ( "../phplog.txt", date ( "Y-m-d H:i:s" ) . "  " . $text . "\r\n", FILE_APPEND );
    }


}
